<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePermissionTables extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        $tableNames = config('permission.table_names');
        $columnNames = config('permission.column_names');

        // 权限表
        Schema::create(
            $tableNames['permissions'],
            function (Blueprint $table) {
                $table->bigIncrements('id')->comment('ID');
                $table->unsignedBigInteger('parent_id')->default(0);
                $table->string('name')->comment('权限名称');
                $table->string('title')->comment('权限标题');
                $table->string('guard_name')->comment('权限分组');
                $table->string('http_method')->comment('HTTP方法');
                $table->string('http_path')->comment('HTTP路径');
                $table->timestamp('created_at')->nullable()->comment('创建时间');
                $table->timestamp('updated_at')->nullable()->comment('修改时间');
            }
        );

        DB::statement('alter table'. ' ' .config('database.connections.mysql.prefix', '').'permissions comment "权限表"');

        // 角色表
        Schema::create(
            $tableNames['roles'],
            function (Blueprint $table) {
                $table->bigIncrements('id')->comment('ID');
                $table->string('name')->comment('角色名称');
                $table->string('title')->comment('角色标题');
                $table->string('guard_name')->comment('角色分组');
                $table->timestamp('created_at')->nullable()->comment('创建时间');
                $table->timestamp('updated_at')->nullable()->comment('修改时间');
            }
        );

        DB::statement('alter table'. ' ' .config('database.connections.mysql.prefix', '').'roles comment "角色表"');

        // 菜单表
        Schema::create(
            $tableNames['menus'],
            function (Blueprint $table) {
                $table->bigIncrements('id')->comment('ID');
                $table->bigInteger('parent_id')->default(0)->comment('父级ID');
                $table->string('title', 50)->comment('名称');
                $table->string('icon', 50)->comment('图标');
                $table->string('uri', 50)->nullable()->comment('URI');
                $table->tinyInteger('is_directory')->default(0)->comment('是否拥有子菜单');
                $table->integer('order')->default(0)->comment('排序');
                $table->timestamp('created_at')->nullable()->comment('创建时间');
                $table->timestamp('updated_at')->nullable()->comment('修改时间');
            }
        );

        DB::statement('alter table'. ' ' .config('database.connections.mysql.prefix', '').'menus comment "菜单表"');

        // 模型权限表
        Schema::create(
            $tableNames['model_has_permissions'],
            function (Blueprint $table) use ($tableNames, $columnNames) {
                $table->unsignedBigInteger('permission_id')->comment('权限ID');

                $table->string('model_type')->comment('模型类型');
                $table->unsignedBigInteger($columnNames['model_morph_key'])->comment('模型ID');
                $table->index([$columnNames['model_morph_key'], 'model_type',]);

                $table->foreign('permission_id')
                    ->references('id')
                    ->on($tableNames['permissions'])
                    ->onDelete('cascade');

                $table->primary(
                    ['permission_id', $columnNames['model_morph_key'], 'model_type'],
                    'model_has_permissions_permission_model_type_primary'
                );
            }
        );

        DB::statement('alter table'. ' ' .env('DB_PREFIX', '').'model_has_permissions comment "模型权限表"');

        // 模型角色表
        Schema::create(
            $tableNames['model_has_roles'],
            function (Blueprint $table) use ($tableNames, $columnNames) {
                $table->unsignedBigInteger('role_id')->comment('角色ID');

                $table->string('model_type')->comment('模型类型');
                $table->unsignedBigInteger($columnNames['model_morph_key'])->comment('模型ID');
                $table->index([$columnNames['model_morph_key'], 'model_type',]);

                $table->foreign('role_id')
                    ->references('id')
                    ->on($tableNames['roles'])
                    ->onDelete('cascade');

                $table->primary(
                    ['role_id', $columnNames['model_morph_key'], 'model_type'],
                    'model_has_roles_role_model_type_primary'
                );
            }
        );

        DB::statement('alter table'. ' ' .config('database.connections.mysql.prefix', '').'model_has_roles comment "模型角色表"');

        // 角色权限表
        Schema::create(
            $tableNames['role_has_permissions'],
            function (Blueprint $table) use ($tableNames) {
                $table->unsignedBigInteger('permission_id')->comment('权限ID');
                $table->unsignedBigInteger('role_id')->comment('角色ID');

                $table->foreign('permission_id')
                    ->references('id')
                    ->on($tableNames['permissions'])
                    ->onDelete('cascade');

                $table->foreign('role_id')
                    ->references('id')
                    ->on($tableNames['roles'])
                    ->onDelete('cascade');

                $table->primary(['permission_id', 'role_id']);

                app('cache')
                    ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
                    ->forget(config('permission.cache.key'));
            }
        );

        DB::statement('alter table'. ' ' .config('database.connections.mysql.prefix', '').'role_has_permissions comment "角色权限表"');

        // 角色菜单表
        Schema::create(
            $tableNames['role_has_menus'],
            function (Blueprint $table) use ($tableNames) {
                $table->unsignedBigInteger('menu_id')->comment('菜单ID');
                $table->unsignedBigInteger('role_id')->comment('角色ID');

                $table->foreign('menu_id')
                    ->references('id')
                    ->on($tableNames['menus'])
                    ->onDelete('cascade');

                $table->foreign('role_id')
                    ->references('id')
                    ->on($tableNames['roles'])
                    ->onDelete('cascade');

                $table->primary(['menu_id', 'role_id']);

                app('cache')
                    ->store(config('menu.cache.store') != 'default' ? config('menu.cache.store') : null)
                    ->forget(config('menu.cache.key'));
            }
        );

        DB::statement('alter table'. ' ' .config('database.connections.mysql.prefix', '').'role_has_menus comment "角色菜单表"');
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        $tableNames = config('permission.table_names');

        Schema::dropIfExists($tableNames['role_has_menus']);            // 角色菜单表
        Schema::dropIfExists($tableNames['role_has_permissions']);      // 角色权限表
        Schema::dropIfExists($tableNames['model_has_roles']);           // 模型角色表
        Schema::dropIfExists($tableNames['model_has_permissions']);     // 模型权限表
        Schema::dropIfExists($tableNames['menus']);                     // 菜单表
        Schema::dropIfExists($tableNames['roles']);                     // 角色表
        Schema::dropIfExists($tableNames['permissions']);               // 权限表
    }
}
